﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BToolkit
{
    public class NamedPipeServer
    {
        private NamedPipeServerStream pipeServer;
        private Thread listenThread;
        public event Action onClientConnected;
        public event Action onClientDisconnected;
        public event Action<string> onMessageReceived;

        public NamedPipeServer(string pipeName)
        {
            pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            listenThread = new Thread(ListenForClients);
            listenThread.Start();
            Log("启动");
        }

        private void ListenForClients()
        {
            while (true)
            {
                try
                {
                    pipeServer.WaitForConnection();
                    onClientConnected?.Invoke();
                    Log($"有客户连接");

                    var reader = new StreamReader(pipeServer, Encoding.UTF8);
                    while (pipeServer.IsConnected)
                    {
                        string message = reader.ReadLine();
                        if (message != null)
                        {
                            Log($"收到客户端发来的消息：{message}");
                            onMessageReceived?.Invoke(message);
                        }
                    }
                }
                catch (IOException)
                {
                    Log($"服务已断开或有客户断开");
                    onClientDisconnected?.Invoke();
                }
            }
        }

        public void SendMsg(string message)
        {
            if (!pipeServer.IsConnected)
            {
                Log("SendMsg(" + message + ")失败，当前暂无客户端连接");
                return;
            }
            var writer = new StreamWriter(pipeServer, Encoding.UTF8);
            writer.WriteLine(message);
            writer.Flush();
        }

        public void Close()
        {
            if (pipeServer.IsConnected)
            {
                pipeServer.Disconnect();
            }
            pipeServer.Close();
            Log("Close()");
        }

        private void Log(object msg)
        {
            Debug.Log($"[NamedPipeServer] " + msg);
        }
    }
}
